/*
 * Test every method except:
 * searchTerms as it requires display
 */

package tester;

import static org.junit.Assert.*;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.GregorianCalendar;

import logic.Find;
import memory.GenericEvents;
import memory.Memory;

import org.junit.Test;

import storage.Storage;

public class TestFind extends Storage{
	
	//@author A0085082E
	@Test
	public void test() {
		Memory testMem = new Memory();
		Storage.setSaveFileAddress("test2.txt");
		Storage.checkForFileExists(testMem);
		
		testSearchExact(testMem);
		testRecursiveSearchTerms(testMem);
		testFindDate(testMem);
	}
	
	private void testSearchExact(Memory testMem){
		testSearchExact_EmptyMem();
		testSearchExact_NonEmptyMem(testMem);
	}
	
	private void testRecursiveSearchTerms(Memory testMem){
		testRecursiveSearchTerms_ZeroTerm(testMem);
		testRecursiveSearchTerms_Space(testMem);
		testRecursiveSearchTerms_OneTerm(testMem);
		testRecursiveSearchTerms_MoreThanOneTerm(testMem);
	}
	
	private void testFindDate(Memory testMem){
		Calendar date = new GregorianCalendar();
		testFindDate_NoneExistent(testMem, date);
		testFindDate_OnEndDate(testMem, date);
		testFindDate_OnStartDate(testMem, date);
		testFindDate_Containing(testMem, date);
	}
	
	
	
	private void testSearchExact_EmptyMem(){
		Memory testMem = new Memory();
		
		ArrayList<GenericEvents> testCase1 = Find.searchExact("I want to eat", testMem);
		assertEquals("If mem is empty, test if searchExact can run without error", testCase1.size(), 0);
	}
	
	private void testSearchExact_NonEmptyMem(Memory testMem){
		
		ArrayList<GenericEvents> testCase1 = Find.searchExact("I want to eat", testMem);
		assertEquals("If mem is not empty, test if item cannot be found", testCase1.size(), 0);
		
		ArrayList<GenericEvents> testCase2 = Find.searchExact("I am hungry", testMem);
		assertEquals("If mem is not empty, test if item can be found", testCase2.size(), 1);
		
	}
	
	private void testRecursiveSearchTerms_ZeroTerm(Memory testMem){
		ArrayList<GenericEvents> result = new ArrayList<GenericEvents>(testMem.getList());
		String[] keywords = {};
		result = Find.recursiveSearchTerms(keywords, 0, result);
		assertEquals("search without criteria", result.size(), 5);
		
	}
	
	private void testRecursiveSearchTerms_Space(Memory testMem){
		ArrayList<GenericEvents> result = new ArrayList<GenericEvents>(testMem.getList());
		String[] keywords = {" "};
		result = Find.recursiveSearchTerms(keywords, 0, result);
		
		//One item without any space out of 5
		assertEquals("search a space", result.size(), 4);
		
	}
	
	private void testRecursiveSearchTerms_OneTerm(Memory testMem){
		ArrayList<GenericEvents> result = new ArrayList<GenericEvents>(testMem.getList());
		String[] keywords = {"hungry"};
		result = Find.recursiveSearchTerms(keywords, 0, result);
		assertEquals("search for single term", result.size(), 2);
		
	}
	
	private void testRecursiveSearchTerms_MoreThanOneTerm(Memory testMem){
		ArrayList<GenericEvents> result = new ArrayList<GenericEvents>(testMem.getList());
		String[] keywords = {"hungry", "very", "chicken"};
		result = Find.recursiveSearchTerms(keywords, 0, result);
		assertEquals("search for more than 1 term successful", result.size(), 1);
		
		ArrayList<GenericEvents> result2 = new ArrayList<GenericEvents>(testMem.getList());
		String[] keywords2 = {"hungry", "very", "chicken", "still"};
		result2 = Find.recursiveSearchTerms(keywords2, 0, result2);
		assertEquals("search for more than 1 term unsuccessful", result2.size(), 0);
		
	}
	
	//Completely outside of any range
		private void testFindDate_NoneExistent(Memory testMem, Calendar date){
			
			date.set(1999, 10, 9);
			ArrayList<GenericEvents> result1 =  Find.findDate(date, testMem);
			assertEquals("Cannot find date required", result1.size(), 0);
			
			//A day before earliest startdate
			date.set(2013, 7, 26);
			result1 =  Find.findDate(date, testMem);
			assertEquals("Cannot find date required", result1.size(), 0);
			
			//A day after latest enddate
			date.set(2015, 5, 31);
			result1 =  Find.findDate(date, testMem);
			assertEquals("Cannot find date required", result1.size(), 0);
			
		}
		
		private void testFindDate_OnEndDate(Memory testMem, Calendar date){
			
			date.set(2015, 4, 30);
			ArrayList<GenericEvents> result1 =  Find.findDate(date, testMem);
			assertEquals("Only 1 item has this enddate", result1.size(), 1);
			
		}
		
		private void testFindDate_OnStartDate(Memory testMem, Calendar date){
			
			date.set(2013, 8, 27);
			ArrayList<GenericEvents> result2 =  Find.findDate(date, testMem);
			assertEquals("Only 1 item has this start date", result2.size(), 1);
			
		}
		
		private void testFindDate_Containing(Memory testMem, Calendar date){
			date.set(2014, 1, 27);
			ArrayList<GenericEvents> result3 =  Find.findDate(date, testMem);
			assertEquals("Date within start and end range", result3.size(), 4);
		}
	
	

}
